<?php

namespace App\Service;

use App\Constant\Error;
use App\Http\Controllers\WechatController;
use App\Jobs\SendWechatTemplateMsg;
use App\Models\Apply;
use App\Models\ApplyReview;
use App\Models\Permission;
use App\Models\Role;
use App\Repositories\Eloquent\ApplyRepositoryEloquent;
use App\Service\Admin\BaseService;
use App\User;
use DB;
use Log;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redis;
use Serializable;

/**
 * 活动service
 */
class ApplyService extends BaseService
{

    private $apply;

    function __construct(ApplyRepositoryEloquent $apply)
    {
        $this->apply = $apply;
    }

    /**
     * datatables获取数据
     * @author 晚黎
     * @date   2016-11-02T10:31:46+0800
     * @return [type]                   [description]
     */
    public function ajaxIndex()
    {
        // datatables请求次数
        $draw = request('draw', 1);
        // 开始条数
        $start = request('start', config('admin.golbal.list.start'));
        // 每页显示数目
        $length = request('length', config('admin.golbal.list.length'));
        // datatables是否启用模糊搜索
        $search['regex'] = request('search.regex', false);
        // 搜索框中的值
        $search['value'] = request('search.value', '');
        // 排序
        $order['name'] = request('columns.' . request('order.0.column', 0) . '.name');
        $order['dir'] = request('order.0.dir', 'asc');

        $cond = [];
        /*前端排序*/
        $relation = [
            1 => 'apply',
            3 => 'province',
            6 => 'degree',
            7 => 'grade',
            9 => 'stage',
            10 => 'status',
        ];
        foreach ($relation as $key => $item) {
            $value = request('columns.' . $key . '.search.value');
            if ($value !== '' && $value !== 'false') {
                $cond[$item] = $value;
            }
        }

        //展示所有？默认展示未审核,借助第一列筛选
        $all = request('columns.0.search.value');
        $all = $all == 2 ? true : false;

        $result = $this->apply->getApplyList($start, $length, $search, $order, $cond, $all);

        $activities = [];

        if ($result['apply']) {
            foreach ($result['apply'] as $v) {
                $v->actionButton = $v->actionButton . '<a href="' . url('admin/apply/' . $v->id) . '" class="btn btn-xs btn-outline btn-primary tooltips" data-original-title="查看"  data-placement="top"><i class="fa fa-eye"></i></a> ';
                if (getUser()->isAdmin()) {
                    $v->actionButton = $v->actionButton . '<a href="' . url('admin/apply/' . $v->id . '/delete') . '" class="btn btn-xs btn-outline btn-danger tooltips destroy_item" data-original-title="删除"  data-placement="top"><i class="fa fa-trash"></i></a> ';
                }
                $activities[] = $v;
            }
        }

        return [
            'draw' => $draw,
            'recordsTotal' => $result['count'],
            'recordsFiltered' => $result['count'],
            'data' => $activities,
        ];
    }

    /**
     * 添加活动
     * @author 晚黎
     * @date   2016-11-02T10:32:18+0800
     * @param  [type]                   $formData [表单中所有的数据]
     * @return [type]                             [true or false]
     */
    public function storeApply($request)
    {
        $formData = $request->all();
        Log::debug('提交的表单: openid[' . getOpenid() . '] content:' . json_encode($formData));
        //检查openid，一个月只能提交一次
        $openid = getOpenid();
        $count = Apply::where('openid', $openid)->whereDate('created_at', '>', date('Y-m-d', strtotime('-1 month')))->count();
        if ($count > 0 && $openid != 'oHwEGs2nlJMpKJO7Id7-cIJOq7cY') {
            return Error::getError(Error::APPLY_OPENID_LIMIT);
        }

        //检查岗位
        $grade = $formData['grade'];
        $canApply = Apply::getApply($grade);
        $apply = intval($formData['apply']);
        if (!in_array($apply, $canApply)) {
            return Error::getError(Error::APPLY_GRADE_INVALID);
        }

        $formData['status'] = Apply::STATUS_UNREAD;
        $formData['stage'] = Apply::STAGE_1;
        $formData['openid'] = $openid;

        $result = $this->apply->create($formData);

        if ($result) {
            dispatch(new SendWechatTemplateMsg(__CLASS__ . '::sendApplySuccessMsgToUser', [$result]));
            dispatch(new SendWechatTemplateMsg(__CLASS__ . '::sendReviewRemindMsgToAdmin', [$result]));
        }
        return Error::getError(Error::OK);
    }

    /**
     * 根据ID获取活动数据
     * @author 晚黎
     * @date   2016-11-02T11:44:36+0800
     * @param  [type]                   $id [活动id]
     * @return [type]                       [查询出来的活动对象，查不到数据时跳转404]
     */
    public function getApplyById($id)
    {
        $apply = $this->apply->find($id);
        if ($apply) {
            return $apply;
        }
        abort(404);
    }

    /**
     * 修改活动
     * @author 晚黎
     * @date   2016-11-02T12:45:00+0800
     * @param  [type]                   $attributes [表单数据]
     * @param  [type]                   $id         [resource路由传递过来的id]
     * @return [type]                               [true or false]
     */
    public function updateApply($attributes, $id)
    {
        // 防止用户恶意修改表单id，如果id不一致直接跳转500
        if ($attributes['id'] != $id) {
            abort(500);
        }
        try {
            $attributes['start_grab_date'] = strtotime($attributes['start_grab_date']);
            $attributes['end_grab_date'] = strtotime($attributes['end_grab_date']);
            $attributes['start_date'] = strtotime($attributes['start_date']);
            $attributes['end_date'] = strtotime($attributes['end_date']);
            $result = $this->apply->update($attributes, $id);
            flash_info($result, trans('act/alert.apply.edit_success'), trans('act/alert.apply.edit_error'));
            return $result;
        } catch (Exception $e) {
            // 错误信息发送邮件
            $this->sendSystemErrorMail(env('MAIL_SYSTEMERROR', ''), $e);
            return false;
        }
    }

    /**
     * 活动暂不做状态管理，直接删除
     * @author 晚黎
     * @date   2016-11-02T13:23:45+0800
     * @param  [type]                   $id [活动id]
     * @return [type]                       [true or false]
     */
    public function destroyApply($id)
    {
        try {
            $result = $this->apply->delete($id);
            flash_info($result, '删除成功', '删除失败');
            return $result;
        } catch (Exception $e) {
            // 错误信息发送邮件
            $this->sendSystemErrorMail(env('MAIL_SYSTEMERROR', ''), $e);
            return false;
        }

    }

    /**
     * 审核
     * @return mixed
     */
    public function review()
    {
        $user = getUser();
        $applyId = request('id');
        $apply = $this->apply->find($applyId);
        if (empty($apply)) {
            return Error::getError(Error::NOT_EXIST);
        }

        //检查阶段
        $stage = $apply->stage;
        if (!$user->can('stage.' . $stage)) {
            return Error::getError(Error::NO_PERMISSION);
        }

        //检查状态
        if (in_array($apply->status, [Apply::STATUS_PASS, Apply::STATUS_REFUSE])) {
            return Error::getError(Error::APPLY_STATUS_INVALID);
        }
        $status = intval(request('status'));
        if (!in_array($status, [Apply::STATUS_PASS, Apply::STATUS_REFUSE, Apply::STATUS_UNDETERMINED])) {
            return Error::getError(Error::INVALID_PARAM, 'status');
        }

        DB::beginTransaction();

        //保存审核内容
        $review = new ApplyReview();
        $review->apply_id = $applyId;
        $review->admin_id = $user->id;
        $review->status = $status;
        $review->stage = $stage;
        $review->evaluation = request('evaluation');
        $review->remark = request('remark');
        $r = $review->save();
        if (!$r) {
            DB::rollBack();
            return Error::getError(Error::DB_ERROR);
        }

        //更新apply数据
        if ($status == Apply::STATUS_PASS && !Apply::isLastStage($apply)) {
            $apply->stage = $stage + 1;
            $apply->status = Apply::STATUS_UNREAD;
        } else {
            $apply->status = $status;
        }
        $r = $apply->save();
        if (!$r) {
            DB::rollBack();
            return Error::getError(Error::DB_ERROR);
        }

        if ($apply->status != Apply::STATUS_UNDETERMINED) {
            dispatch(new SendWechatTemplateMsg(__CLASS__ . '::sendReviewMsgToUser', [$apply]));
            dispatch(new SendWechatTemplateMsg(__CLASS__ . '::sendReviewRemindMsgToAdmin', [$apply]));
        }

        DB::commit();
        return Error::getError(Error::OK);
    }

    /**
     * 统计
     * @return mixed
     */
    public function stat()
    {
        $totalCount = Apply::count();
        $todayCount = Apply::whereDate('created_at', date('Y-m-d'))->count();
        $notReviewCount = Apply::notReview()->count();
//        $hasReviewCount = $totalCount - $notReviewCount;
        $data['stat'] = [
            'total' => $totalCount,
            'today' => $todayCount,
            'notReview' => $notReviewCount,
//            'hasReview' => $hasReviewCount,
        ];

        $user = getUser();
        if ($user->isAdmin()) {
            $locationStat = [];
            $locations = Role::location()->get();
            $start = strlen(Permission::PROVINCE_PRE);
            foreach ($locations as $location) {
                $provinces = [];
                foreach ($location->permissions as $permission) {
                    if (starts_with($permission->slug, Permission::PROVINCE_PRE)) {
                        $provinces[] = substr($permission->slug, $start);
                    }
                }
                $count = Apply::whereIn('province', $provinces)->count();
                $locationStat[] = [
                    'location' => $location->name,
                    'count' => $count,
                ];
            }
            $data['locationStat'] = $locationStat;
        }
        return $data;
    }

    /**
     * 发送报名成功通知
     * @param $apply
     */
    public static function sendApplySuccessMsgToUser($apply)
    {
        $wechat = WechatController::app();
        $data = [
            'touser' => $apply->openid,
            'template_id' => '3KJ9FIaQoZYNrOz8GRt1TQGzy2hlfAX_NwUxqviYPr0',
            'url' => '',
            'data' => [
                "first" => array("您的魅联盟报名申请已提交成功。\n", '#8d8d8d'),
                "keyword1" => array("魅联盟2018校园大使招募", "#000000"),
                "keyword2" => array("初审中", "#000000"),
                "keyword3" => array($apply->name, "#000000"),
                "remark" => array("\n若简历合适，我们会在10个工作日内联系你电话面试，请保持联系方式畅通。", "#5599FF"),//ff2600
            ],
        ];
        Log::debug('发送微信模板消息 报名成功 applyid:' . $apply->id . ' openid:' . $apply->openid . ' name:' . $apply->name);
        $wechat->notice->send($data);
    }

    /**
     * 提醒用户审批结果
     * @param $apply
     *
     */
    public static function sendReviewMsgToUser($apply)
    {
        $wechat = WechatController::app();
        $pass = $apply->status != Apply::STATUS_REFUSE;//是否通过
        $stageType = Apply::$stageType[$apply->stage];//当前阶段
        $kw2Data = $pass ? ($apply->status == Apply::STATUS_PASS ? "待加入" : "{$stageType}中") : "{$stageType}未通过";

        $oldStageType = $apply->status != Apply::STATUS_UNREAD ? $stageType : Apply::$stageType[$apply->stage - 1];//上一阶段
        $firstData = $pass ? "恭喜你，你的魅联盟报名申请已通过{$oldStageType}。\n" : "很遗憾，你的魅联盟报名申请未通过{$oldStageType}。\n";
        $kw3Data = date('Y年m月d日 H:i');
        $remarkData = $pass ?
            ($apply->status == Apply::STAGE_2 ?
                "\n恭喜你成为准魅联盟成员，请在电脑和手机中下载「钉钉」并使用报名电话注册账号，我们会在7个工作日左右将你拉入魅联盟钉钉架构。"
                : "\n我们会在10个工作日内" . ($stageType == '终审' ? "完成终审，请耐心等待。" : "联系你电话面试，请保持联系方式畅通。"))
            : "\n非常荣幸收到您的报名，经过我们评估，认为您目前与该岗位不太匹配，暂时无法录用您。您已被列入我们的人才库，相信更好的机会一定还在翘首期盼您。";
        $remarkColor = $pass ? '#5599FF' : '#ff2600';
        $data = [
            'touser' => $apply->openid,
            'template_id' => 'rDH30F9Rl4ZNzH7FZ9bFyTLO7RPB1K6Ts-vYBoIWcJM',
            'url' => '',
            'data' => [
                "first" => array($firstData, '#8d8d8d'),
                "keyword1" => array("魅联盟2018校园大使招募", "#000000"),
                "keyword2" => array($kw2Data, "#000000"),
                "keyword3" => array($kw3Data, "#000000"),
                "remark" => array($remarkData, $remarkColor),
            ],
        ];
        Log::debug('发送微信模板消息 审核通知 applyid:' . $apply->id . ' openid:' . $apply->openid . ' user:' . $apply->name);
        $wechat->notice->send($data);
    }


    /**
     * 发送审核提醒通知
     * @param $apply
     * @internal param $openid
     * @internal param $url
     * @internal param $name
     */
    public static function sendReviewRemindMsgToAdmin($apply)
    {
        if (in_array($apply->status, [Apply::STATUS_PASS, Apply::STATUS_REFUSE])) {
            return;
        }
        $wechat = WechatController::app();
        $applyType = Apply::$applyType[$apply->apply];
        $data = [
            'touser' => $apply->openid,
            'template_id' => 'P3ib0LvUPLZP_DaWiKKWw2F52XGXZyyrMcWjhwJoLFU',
            'url' => url('admin/apply/' . $apply->id),
            'data' => [
                "first" => array("你有⼀条报名申请需审批。\n", '#8d8d8d'),
                "keyword1" => array($apply->city, "#000000"),
                "keyword2" => array($apply->school, "#000000"),
                "keyword3" => array($apply->zone, "#000000"),
                "keyword4" => array($apply->name, "#000000"),
                "keyword5" => array($applyType, "#000000"),
                "remark" => array("\n点击详情可直接审批，请尽快处理。", "#5599FF"),//ff2600
            ],
        ];
        $admins = self::getAdminsByApply($apply);
        if ($admins) {
            $admins->map(function ($admin) use ($wechat, $apply, $data) {
                if (!empty($admin->openid)) {
                    $data['touser'] = $admin->openid;
                    Log::debug('发送微信模板消息 审核提醒 applyid:' . $apply->id . ' openid:' . $admin->openid . ' admin:' . $admin->name);
                    $wechat->notice->send($data);
                }
            });
        }
    }


    /**
     * 获取管理员
     * @param $apply
     * @return bool|\Illuminate\Database\Eloquent\Collection
     */
    public static function getAdminsByApply($apply)
    {
        if (empty($apply)) {
            return false;
        }
        $stage = $apply->stage;
        $stagePermission = Permission::STAGE_PRE . $stage;
        if (in_array($apply->apply, Apply::$thinkTank)) {
            $applyPermission = Permission::APPLY_PRE . $apply->apply;
            $r = User::all()->filter(function ($user, $key) use ($stagePermission, $applyPermission) {
                return $user->canAll([$stagePermission, $applyPermission]);
            });
        } elseif (in_array($apply->apply, Apply::$notThinkTank)) {
            $provincePermission = Permission::PROVINCE_PRE . $apply->province;
            $r = User::all()->filter(function ($user, $key) use ($stagePermission, $provincePermission) {
                return $user->canAll([$stagePermission, $provincePermission]);
            });
        } else {
            return false;
        }
        return $r;
    }

}